package set_;

import java.util.HashSet;
import java.util.Objects;

public class HashSetIncrement {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();

        //案例1：查看扩容机制
        for(int i=0;i<100;++i){
            hashSet.add(i);
        }
        /**
         * 第一次添加数据扩容到 16
         * (1)
         * 调用resize方法，直接将预值 16 创建一个大小为16的table[Node]数组
         * (2.1)
         * 当执行到添加第12个元素的时候会再次扩容，这是是在
         * todo
         *      ++modCount;
         *         if (++size > threshold)
         *             resize();
         *         afterNodeInsertion(evict);
         *         return null;
         *
         *  (2.2)
         *  调用resize扩容，这次扩容是 将原来的table表空间进行2倍扩容
         *      - (newCap = oldCap << 1) newCap是新的空间大小
         *      - newThr = oldThr << 1;  同样的阈值也扩大为2倍
         *
         *  (2.3)
         *  扩容之后底层创建了一个容量为之前两倍的newTab[Node]数组
         *  并进行循环将之前的table数组中的数据赋值给新表
         *  todo Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
         *
         *  resize()源码
         *  todo
         *      final Node<K,V>[] resize() {
         *         Node<K,V>[] oldTab = table;
         *         int oldCap = (oldTab == null) ? 0 : oldTab.length;
         *         int oldThr = threshold;
         *         int newCap, newThr = 0;
         *         if (oldCap > 0) {
         *             if (oldCap >= MAXIMUM_CAPACITY) {
         *                 threshold = Integer.MAX_VALUE;
         *                 return oldTab;
         *             }
         *             else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
         *                      oldCap >= DEFAULT_INITIAL_CAPACITY)
         *                 newThr = oldThr << 1; // double threshold
         *         }
         *         else if (oldThr > 0) // initial capacity was placed in threshold
         *             newCap = oldThr;
         *         else {               // zero initial threshold signifies using defaults
         *             newCap = DEFAULT_INITIAL_CAPACITY;
         *             newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
         *         }
         *         if (newThr == 0) {
         *             float ft = (float)newCap * loadFactor;
         *             newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
         *                       (int)ft : Integer.MAX_VALUE);
         *         }
         *         threshold = newThr;
         *         @SuppressWarnings({"rawtypes","unchecked"})
         *             Node<K, V>[] newTab = (Node<K,V>[])new Node[newCap];
         *         table = newTab;
         *         if (oldTab != null) {
         *             for (int j = 0; j < oldCap; ++j) {
         *                 Node<K,V> e;
         *                 if ((e = oldTab[j]) != null) {
         *                     oldTab[j] = null;
         *                     if (e.next == null)
         *                         newTab[e.hash & (newCap - 1)] = e;
         *                     else if (e instanceof TreeNode)
         *                         ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
         *                     else { // preserve order
         *                         Node<K,V> loHead = null, loTail = null;
         *                         Node<K,V> hiHead = null, hiTail = null;
         *                         Node<K,V> next;
         *                         do {
         *                             next = e.next;
         *                             if ((e.hash & oldCap) == 0) {
         *                                 if (loTail == null)
         *                                     loHead = e;
         *                                 else
         *                                     loTail.next = e;
         *                                 loTail = e;
         *                             }
         *                             else {
         *                                 if (hiTail == null)
         *                                     hiHead = e;
         *                                 else
         *                                     hiTail.next = e;
         *                                 hiTail = e;
         *                             }
         *                         } while ((e = next) != null);
         *                         if (loTail != null) {
         *                             loTail.next = null;
         *                             newTab[j] = loHead;
         *                         }
         *                         if (hiTail != null) {
         *                             hiTail.next = null;
         *                             newTab[j + oldCap] = hiHead;
         *                         }
         *                     }
         *                 }
         *             }
         *         }
         *         return newTab;
         *     }
         *
         */

        //案例2 链表化的table进化成树
        /**
         * 首先我们知道只有两个对象的hash值相同时，即发生了冲突
         * 才会放在同一个索引下形成链表，所以我们自定义一个类并重写hashCode()
         */
        hashSet=new HashSet();
        for(int i=0;i<13;++i){
            hashSet.add(new A(i));
        }

    }
}
class A{
    private int code;

    public A(int code) {
        this.code = code;
    }

    @Override
    public int hashCode() {
        return 16;//返回同一个hash值
    }
}


